<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Document</title>
    <script>
      /* 数据：
        所谓数据代理，也叫数据劫持，值的是在访问或修改某个对象的某个属性时，通过一段代码拦截行为进行额外值的操作（修改或返回）
        现在理解为：
        有一个对象，可以为其他对象，声明某个属性并且对赋值和取值进行自定义操作

        数据代理对象：
        Object.defineProperty(obj,prop,desc)
        obj：要定义属性的对象
        prop：要定义属性的名称
        desc：属性描述对象，包含三个属性：
            value：属性的值
            writable：属性值是否可以改变
            get：读取属性的函数
            set：设置属性的函数
        
        */

      //经常使用的定义对象和赋值
      /* let Person = {}
        Person.name = '张三';//js中没有属性赋值会自动添加
        Person['sex'] = '男';
        alert(Person.name);
        alert(Person.sex); */

      // Object.defineProperty(obj,prop,desc)作用就是直接在一个对象上定义新的属性并且指定新属性返回和设置值的操作
      //通过 Object.defineProperty()为对象定义属性有两种形式且不能够混合使用 1.数据描述符 2.存取描述符

      //用法一  数据描述符 特有的属性 value writable  使用该方式不能使用getter或setter方法
      /*    let Person = {};
        Object.defineProperty(Person,'name',{
            value:'张三',//添加后属性的值
            writable:true, //是否值可以改变 false是默认值
           
        })

        //尝试改变对象的值
        Person.name = "李四";
        console.log(Person.name);
 */

      //用法二 存取描述符  使用一对get/set函数功能来描述属性
      let Person = {};
      let a = null;

      Object.defineProperty(Person, "name", {
        //当读取Person对象的name属性时，get函数会被调用且需要返回一个值给调用者
        get() {
          console.log("get函数被调用");
          return a;
        },

        //当修改Pserson的name属性时，set函数会被调用，且后收到修改的具体值，进行自定义赋值
        set(value) {
          console.log("set函数被调用");
          a = value;
        },
      });

      Person.name = "Jack";
      console.log(Person.name, a);

      a = "Rose";
      console.log(Person.name, a);
    </script>
  </head>
  <body></body>
</html>


<!-- 
   Vue中的数据代理：
   Vue中数据代理通过vm对象来代理data对象中的属性操作
   vue中数据代理的好处，方便操作data中的数据
   基本原理：
   通过Object.defineProperty()把data中所有属性添加到vm身上，
   且为每个属性添加get set方法 
   在读取data中属性的时候内容去调用get set方法完成数据的读写

   Vue将data中的数据拷贝了一份到_data中，又将_data中的属性提取到Vue实例中，通过数据代理来完成的，其实_data对data进行了数据劫持



 -->